<script lang="ts" setup>
import {ElMessage} from "element-plus";
import {nextTick, onMounted, reactive, ref} from "vue";
import type {Role, SetRoleData, User} from "../../../api/acl/user/type.ts";
import {
  reqAddOrUpdateUser,
  reqAllRoles,
  reqBatchUser,
  reqRemoveUser,
  reqSetUserRole,
  reqUserInfo
} from "../../../api/acl/user";

let userInput = ref<string>('');//收集用户输入

let drawer = ref<boolean>(false); //增改抽屉
let drawer1 = ref<boolean>(false); //分配权限抽屉

let currentPage = ref<number>(1); //当前页
let pageSize = ref<number>(3); //当前页码
let total = ref<number>(0); //总记录数

let checkAll = ref(false); //全选框全选与否状态
let isIndeterminate = ref(false); //全选框非全选状态
let checkedRoles = ref<Role[]>([]); //角色复选框数据
let allRoles = ref<Role[]>([]) //角色全部数据

const userIds = ref<number[]>([]);//存储选中的用户id

const roleParams = ref<SetRoleData>({userId: '', roleIdList: []});

const form = ref();//获取表单元素对象

const userInfo = reactive<User[]>([]);//接受分页的数据
const userParams = reactive<User>({
  id: '',
  username: '',
  name: '',
  password: "",
  phone: '',
  roleName: ''
});//接受用户增加和修改数据

const reqPage = async (page = 1) => {
  currentPage.value = page;
  //发起请求
  const result: any = await reqUserInfo(currentPage.value as number, pageSize.value as number, userInput.value as string)
  if (result.code === 200) {
    userInfo.length = 0;//这个有毛病，删除只能把所有字段置空
    Object.assign(userInfo, result.data.records);
    total.value = result.data.total;
  }
}//发起分页查询

onMounted(async () => {
  await reqPage();
});//组件挂载时请求一下数据

//根据用户名搜索
const searchByChar = async () => {
  //发请求，根据userInput
  try {
    await reqPage();
  } catch (e) {
    ElMessage({type: "warning", message: "请求失败"});
  }
}

//重置
const reset = async () => {
  //清空数据
  userInfo.length = 0;
  //再发请求
  await reqPage();
}

//添加用户
const addUser = () => {
  //清空数据
  Object.assign(userParams, {
    id: '',
    username: '',
    name: '',
    password: "",
    phone: '',
    roleName: ''
  });
  //抽屉出来
  drawer.value = true;
  //清空校验字段
  nextTick(() => {
    form.value.clearValidate("username");
    form.value.clearValidate("name");
    form.value.clearValidate("password");
  });
}

//利用element-plus自带的selection-change事件获取用户id
const getUserIds = (users: User[]) => {
  userIds.value = users.reduce((prev, curr) => {
    prev.push(curr.id as number);
    return prev;
  }, [] as number[]);
}

//批量删除用户
const removeUsers = async () => {
  try {
    await reqBatchUser(userIds.value);
    ElMessage({type: "primary", message: "删除成功"});
    await reqPage();
  } catch (e) {
    ElMessage({type: "warning", message: "删除失败"});
  }
}

//分配角色权限
const assignRoles = async (user: User) => {
  //查询权限信息
  const result = await reqAllRoles(user.id as number);
  if (result.code === 200) {
    allRoles.value = result.data.allRolesList;
    checkedRoles.value = result.data.assignRoles;
  }
  //给userParams赋值
  Object.assign(userParams, user);

  //打开抽屉
  drawer1.value = true;

  //重新判断复选框和全选框状态
  updateCheckboxState();
}
//编辑用户
const editUser = (user: User) => {
  //查询用户信息
  Object.assign(userParams, user);
  //打开抽屉
  drawer.value = true;
  //清除校验
  nextTick(() => {
    form.value.clearValidate("username");
    form.value.clearValidate("name");
    form.value.clearValidate("password");
  })
}
//删除用户
const deleteUser = async (user: User) => {
  try {
    await reqRemoveUser(user.id as number);
    ElMessage({type: "primary", message: "删除成功"});
    //reactive没清掉
    await reqPage(pageSize.value > 1 ? currentPage.value : currentPage.value - 1);
  } catch (e) {
    ElMessage({type: "warning", message: "删除失败"});
  }
}

//表单的校验规则
const validatorUsername = (rule: any, value: string, callBack: any) => {
  if (value && value.length > 3) {
    callBack();
  } else {
    callBack(new Error("至少4位"));
  }
}
const validatorName = (rule: any, value: string, callBack: any) => {
  if (value && value.length > 3) {
    callBack();
  } else {
    callBack(new Error("至少三位"));
  }
}
const validatorPassword = (rule: any, value: string, callBack: any) => {
  if (value && value.length > 3) {
    callBack();
  } else {
    callBack(new Error("至少三位"));
  }
}

//表单校验
const rules = {
  username: [{required: true, trigger: "blur", validator: validatorUsername}],
  name: [{required: true, trigger: "blur", validator: validatorName}],
  password: [{trigger: "blur", validator: validatorPassword}],
}

//取消操作
const cancelOption = () => {

  drawer.value = false;//返回
  drawer1.value = false;//返回
}
//确认添加用户
const confirmOption = async () => {
  try {
    await form.value.validate();
    const result = await reqAddOrUpdateUser(userParams);
    if (result.code === 200) {
      ElMessage({type: "success", message: !!userParams.id ? "保存成功" : "更新成功"});
      drawer.value = false;//返回
      await reqPage(!!userParams.id ? currentPage.value : 1);//添加留在第一页，修改留在当前页
      window.location.reload();//让浏览器重新加载，⊥分页查询留在第几页已经没有意义
    } else {
      ElMessage({type: "error", message: !!userParams.id ? "保存失败" : "更新失败"});
    }
  } catch (e) {
    ElMessage({type: "warning", message: "校验不通过"});
  }

}

//控制全选框和复选框状态之全选框
const handleCheckAllChange = (value: boolean) => {
  checkedRoles.value = value ? allRoles.value : [];//根据全选框的状态给checkedRoles赋值
  isIndeterminate.value = false;//allCheckbox改变了，就取消他们的状态
}
//控制全选框和复选框状态之复选框
const handleCheckedCitiesChange = (value: string[]) => {
  checkAll.value = value.length === allRoles.value.length;//如果长度相同，全选
  isIndeterminate.value = checkedRoles.value.length > 0 && value.length < allRoles.value.length
}

//请求用户职位后，修改全选框数据
const updateCheckboxState = () => {
  const allRolesLength = allRoles.value.length;
  const checkedRolesLength = checkedRoles.value.length;

  if (checkedRolesLength === 0) {//已分配职位长度为0，就取消
    checkAll.value = false;
    isIndeterminate.value = false;
  } else if (checkedRolesLength === allRolesLength) {//全部选中
    checkAll.value = true;
    isIndeterminate.value = false
  } else { //未全选，未没选
    checkAll.value = false;
    isIndeterminate.value = true;
  }

}

//保存用户职位信息
const saveRoles = async () => {
  //封装数据
  roleParams.value.roleIdList = checkedRoles.value.reduce((prev, curr) => {
    prev.push(curr.id as number);
    return prev;
  }, [] as number[]);
  roleParams.value.userId = userParams.id as number;

  //开始发请求
  try {
    await reqSetUserRole(roleParams.value as SetRoleData);
    ElMessage({type: "success", message: !!roleParams.value.userId ? "更新成功" : "保存成功"});
    await reqPage(currentPage.value);
  } catch (e) {
    ElMessage({type: "error", message: !!roleParams.value.userId ? "更新失败" : "保存失败"});
  }

  //返回
  drawer1.value = false;
}
</script>

<template>
  <el-card>
    <el-form class="container" inline>
      <el-form-item class="form1" label="用户名">
        <el-input v-model.trim="userInput" class="c1" placeholder="输入用户名"></el-input>
      </el-form-item>
      <el-form-item class="form1">
        <el-button :disabled="userInput.length === 0" class="c1" type="primary" @click="searchByChar">搜索</el-button>
        <el-button class="c1" type="primary" @click="reset">重置</el-button>
      </el-form-item>
    </el-form>
  </el-card>

  <el-card style="margin-top: 10px">
    <el-button type="primary" @click="addUser">添加</el-button>
    <el-button :disabled="userIds.length === 0" type="danger" @click="removeUsers">批量删除</el-button>
    <el-table @selection-change="getUserIds" :cell-style="{textAlign: 'center'}" :data="userInfo" :header-cell-style="{textAlign: 'center'}" border
              style="margin: 10px 0">
      <el-table-column type="selection"></el-table-column>
      <el-table-column label="#" show-overflow-tooltip type="index" width="50px"></el-table-column>
      <el-table-column label="id" prop="id" show-overflow-tooltip width="50px"></el-table-column>
      <el-table-column label="用户名称" prop="username" show-overflow-tooltip></el-table-column>
      <el-table-column label="用户昵称" prop="name" show-overflow-tooltip></el-table-column>
      <el-table-column label="用户角色" prop="roleName" show-overflow-tooltip></el-table-column>
      <el-table-column label="创建时间" prop="createTime" show-overflow-tooltip></el-table-column>
      <el-table-column label="更新时间" prop="updateTime" show-overflow-tooltip></el-table-column>
      <el-table-column label="操作" width="360px">
        <template #default="{row}">
          <el-button icon="Avatar" type="primary" @click="assignRoles(row)">分配角色</el-button>
          <el-button icon="Edit" type="warning" @click="editUser(row)">编辑</el-button>
          <el-button icon="Delete" type="danger" @click="deleteUser(row)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>
    <el-pagination
        v-model:current-page="currentPage"
        v-model:page-size="pageSize"
        :page-sizes="[3, 5, 7, 9]"
        :total="total"
        background
        layout="prev, pager, next, jumper, ->, total, sizes"
        @size-change="reqPage(1)"
        @current-change="reqPage(currentPage)"
    ></el-pagination>
  </el-card>
  <el-drawer v-model="drawer" :title="userParams.id ? '修改用户' : '新增用户'">
    <template #default>
      <el-form ref="form" :model="userParams" :rules="rules">
        <el-form-item label="用户姓名" prop="name">
          <el-input v-model.trim="userParams.name" placeholder="输入用户姓名"></el-input>
        </el-form-item>
        <el-form-item label="用户昵称" prop="username">
          <el-input v-model.trim="userParams.username" placeholder="输入用户昵称"></el-input>
        </el-form-item>
        <el-form-item v-if="!!userParams.id" label="用户密码" prop="password">
          <el-input v-model.trim="userParams.password" placeholder="输入用户密码"></el-input>
        </el-form-item>
      </el-form>
    </template>
    <template #footer>
      <el-button type="info" @click="cancelOption">取消</el-button>
      <el-button type="primary" @click="confirmOption">确认</el-button>
    </template>
  </el-drawer>
  <el-drawer v-model="drawer1" title="分配角色(职位)">
    <template #default>
      <el-form>
        <el-form-item label="用户姓名">
          <el-input v-model="userParams.username" disabled></el-input>
        </el-form-item>
        <el-form-item label="职位列表">
          <el-checkbox
              v-model="checkAll"
              :indeterminate="isIndeterminate"
              @change="handleCheckAllChange"
          >全选
          </el-checkbox>
          <el-checkbox-group
              v-model="checkedRoles"
              @change="handleCheckedCitiesChange"
          >
            <el-checkbox
                v-for="(role, index) in allRoles"
                :key="index"
                :label="role.roleName"
                :value="role"
            >
              {{ role.roleName }}
            </el-checkbox>
          </el-checkbox-group>
        </el-form-item>
      </el-form>
    </template>
    <template #footer>
      <el-button @click="saveRoles" type="primary">保存</el-button>
      <el-button @click="cancelOption" type="text">取消</el-button>
    </template>
  </el-drawer>
</template>

<style scoped>
/**
此处省略300字
 */
.container {
  display: flex;
  justify-content: space-between;
}
</style>